﻿using System;
using System.Collections;
using Anderson.NetLobby.Client;
using Anderson.NetLobby.Common;
using Anderson.NetLobby.MessageContent;
using UnityEngine;
using System.Collections.Concurrent;

public class DemoRoom : MonoBehaviour {

    NetLobbyClientEx client;

    const uint CLIENT_L2_BIZ_TEST01         = 0x02800100;

    const uint CLIENT_L3_BIZ_TEST01_COLOR   = 0x02800101;
    const uint CLIENT_L3_BIZ_TEST01_ROTATE  = 0x02800102;

    public Transform TargetGroup;

    void Start () {
        client = DemoClient.ClientInstance;
	}

    ConcurrentQueue<Action> actionQueue = new ConcurrentQueue<Action>();
    Action normalAction;

    #region Singlton
    void Awake()
    {
        if (m_instance != null)
        {
            Debug.LogError("Another instance of DemoRoom already exist");
        }

        m_instance = this;
    }

    private void OnDestroy()
    {
        m_instance = null;
    }

    private static DemoRoom m_instance = null;
    public static DemoRoom Instance
    {
        get
        {
            return m_instance;
        }
    }
    #endregion



    void Update()
    {
        //while (actionQueue.TryDequeue(out normalAction))
        //{
        //    normalAction.Invoke();
        //}

        if (actionQueue.TryDequeue(out normalAction))
        {
            normalAction.Invoke();
        }
    }

    public void OnSendColor(GameObject go)
    {
        Color c = UnityEngine.Random.ColorHSV();

        MC_GameObjectMessage goMsg = new MC_GameObjectMessage();
        goMsg.playerId = client.PlayerId;
        goMsg.roomId = client.RoomId;
        goMsg.opType = 1;        
        goMsg.targetCode = go.name;
        goMsg.r = c.r;
        goMsg.g = c.g;
        goMsg.b = c.b;
        goMsg.a = c.a;

        NetMessage<MC_GameObjectMessage> netMessageSend = new NetMessage<MC_GameObjectMessage>(
            client.RoomId,
            MessageLevelDefinition.CLIENT_L1_BIZ,
            CLIENT_L2_BIZ_TEST01,
            CLIENT_L3_BIZ_TEST01_COLOR,
            goMsg);

        byte[] bytes = MessageSerialize.Serialize(netMessageSend);

        client.SendBusinessNetMessage(bytes);
    }

    public void OnSendRotate(GameObject go)
    {
        MC_GameObjectMessage goMsg = new MC_GameObjectMessage();
        goMsg.playerId = client.PlayerId;
        goMsg.roomId = client.RoomId;
        goMsg.opType = 2;
        goMsg.targetCode = go.name;
        goMsg.rotateStatus = go.GetComponent<RotateSelf>().enabled ? 0 : 1;

        NetMessage<MC_GameObjectMessage> netMessageSend = new NetMessage<MC_GameObjectMessage>(
            client.RoomId,
            MessageLevelDefinition.CLIENT_L1_BIZ,
            CLIENT_L2_BIZ_TEST01,
            CLIENT_L3_BIZ_TEST01_ROTATE,
            goMsg);

        byte[] bytes = MessageSerialize.Serialize(netMessageSend);

        client.SendBusinessNetMessage(bytes);
    }

    internal void OnBusinessMessageReceive(byte[] fullMessageBytes, long roomId, uint l1, uint l2, uint l3)
    {
        Debug.Log("DemoRoom.OnBusinessMessageReceive");

        if (l2 == CLIENT_L2_BIZ_TEST01)
        {
            NetMessage<MC_GameObjectMessage> netMessage = MessageSerialize.Deserialize<MC_GameObjectMessage>(fullMessageBytes);
            MC_GameObjectMessage content = netMessage.MessageContent;

            if (l3 == CLIENT_L3_BIZ_TEST01_COLOR)
            {
                actionQueue.Enqueue(() => {
                    //DoChangeColor(content);
                    StartCoroutine(DoChangeColorAsync(content));
                });                
            }
            if (l3 == CLIENT_L3_BIZ_TEST01_ROTATE)
            {
                actionQueue.Enqueue(() => {
                    DoChangeRotate(content);                    
                });
            }
        }
    }

    private void DoChangeRotate(MC_GameObjectMessage content)
    {
        Transform t = TargetGroup.Find(content.targetCode);
        if (null != t)
        {
            RotateSelf rs = t.gameObject.GetComponent<RotateSelf>();
            if (null != rs)
            {
                rs.enabled = content.rotateStatus == 0 ? false : true;
            }
        }
    }

    IEnumerator DoChangeColorAsync(MC_GameObjectMessage content)
    {
        yield return null;

        Transform t = TargetGroup.Find(content.targetCode);
        if (null != t)
        {
            Material m = t.gameObject.GetComponent<Renderer>().material;

            if (null != m)
            {
                Color c = new Color(content.r, content.g, content.b, content.a);
                m.color = c;
            }
        }
    }

    private void DoChangeColor(MC_GameObjectMessage content)
    {
        Transform t = TargetGroup.Find(content.targetCode);
        if (null != t)
        {
            Material m = t.gameObject.GetComponent<Renderer>().material;

            if (null != m)
            {
                Color c = new Color(content.r, content.g, content.b, content.a);
                m.color = c;
            }
        }
    }
}
